server-side-props.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
  2. import {
  3. getServerSideI18nProps, getServerSideUserUISettingsProps, getServerSideCommonInitialProps, getServerSideCommonEachProps,
  4. } from '../common-props';
  5. import type { InitialProps, SameRouteEachProps } from '../general-page';
  6. import {
  7. getServerSideConfigurationProps, getServerSideRendererConfigProps, getServerSideSidebarConfigProps,
  8. getActivityAction, isValidInitialAndSameRouteProps, isValidSameRouteProps,
  9. } from '../general-page';
  10. import { addActivity } from '../utils/activity';
  11. import { mergeGetServerSidePropsResults } from '../utils/server-side-props';
  12. import { NEXT_JS_ROUTING_PAGE } from './consts';
  13. import { getPageDataForInitial, getPageDataForSameRoute } from './page-data-props';
  14. const nextjsRoutingProps = {
  15. props: {
  16. nextjsRoutingPage: NEXT_JS_ROUTING_PAGE,
  17. },
  18. };
  19. export async function getServerSidePropsForInitial(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<InitialProps & SameRouteEachProps>> {
  20. //
  21. // STAGE 1
  22. //
  23. const commonEachPropsResult = await getServerSideCommonEachProps(context);
  24. // Handle early return cases (redirect/notFound)
  25. if ('redirect' in commonEachPropsResult || 'notFound' in commonEachPropsResult) {
  26. return commonEachPropsResult;
  27. }
  28. const commonEachProps = await commonEachPropsResult.props;
  29. // Handle redirect destination from common props
  30. if (commonEachProps.redirectDestination != null) {
  31. return {
  32. redirect: {
  33. permanent: false,
  34. destination: commonEachProps.redirectDestination,
  35. },
  36. };
  37. }
  38. //
  39. // STAGE 2
  40. //
  41. const [
  42. commonInitialResult,
  43. userUIResult,
  44. serverConfigResult,
  45. rendererConfigResult,
  46. sidebarConfigResult,
  47. i18nPropsResult,
  48. pageDataResult,
  49. ] = await Promise.all([
  50. getServerSideCommonInitialProps(context),
  51. getServerSideUserUISettingsProps(context),
  52. getServerSideConfigurationProps(context),
  53. getServerSideRendererConfigProps(context),
  54. getServerSideSidebarConfigProps(context),
  55. getServerSideI18nProps(context, ['translation']),
  56. getPageDataForInitial(context),
  57. ]);
  58. // Merge all results in a type-safe manner (using sequential merging)
  59. const mergedResult = mergeGetServerSidePropsResults(commonEachPropsResult,
  60. mergeGetServerSidePropsResults(commonInitialResult,
  61. mergeGetServerSidePropsResults(userUIResult,
  62. mergeGetServerSidePropsResults(serverConfigResult,
  63. mergeGetServerSidePropsResults(rendererConfigResult,
  64. mergeGetServerSidePropsResults(sidebarConfigResult,
  65. mergeGetServerSidePropsResults(i18nPropsResult,
  66. mergeGetServerSidePropsResults(pageDataResult, nextjsRoutingProps))))))));
  67. // Check for early return (redirect/notFound)
  68. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  69. return mergedResult;
  70. }
  71. const mergedProps = await mergedResult.props;
  72. // Type-safe props validation AFTER skipSSR is properly set
  73. if (!isValidInitialAndSameRouteProps(mergedProps)) {
  74. throw new Error('Invalid merged props structure');
  75. }
  76. await addActivity(context, getActivityAction(mergedProps));
  77. return mergedResult;
  78. }
  79. export async function getServerSidePropsForSameRoute(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<SameRouteEachProps>> {
  80. //
  81. // STAGE 1
  82. //
  83. const commonEachPropsResult = await getServerSideCommonEachProps(context);
  84. // Handle early return cases (redirect/notFound)
  85. if ('redirect' in commonEachPropsResult || 'notFound' in commonEachPropsResult) {
  86. return commonEachPropsResult;
  87. }
  88. const commonEachProps = await commonEachPropsResult.props;
  89. // Handle redirect destination from common props
  90. if (commonEachProps.redirectDestination != null) {
  91. return {
  92. redirect: {
  93. permanent: false,
  94. destination: commonEachProps.redirectDestination,
  95. },
  96. };
  97. }
  98. //
  99. // STAGE 2
  100. //
  101. // Get page data
  102. const sameRoutePageDataResult = await getPageDataForSameRoute(context);
  103. // Merge results in a type-safe manner
  104. const mergedResult = mergeGetServerSidePropsResults(commonEachPropsResult,
  105. mergeGetServerSidePropsResults(sameRoutePageDataResult, nextjsRoutingProps));
  106. // Check for early return (redirect/notFound)
  107. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  108. return mergedResult;
  109. }
  110. // Validate the merged props have all required properties
  111. if (!isValidSameRouteProps(mergedResult.props)) {
  112. throw new Error('Invalid same route props structure');
  113. }
  114. // -- TODO: persist activity
  115. // const mergedProps = await mergedResult.props;
  116. // // Type-safe props validation AFTER skipSSR is properly set
  117. // if (!isValidSameRouteProps(mergedProps)) {
  118. // throw new Error('Invalid same route props structure');
  119. // }
  120. // await addActivity(context, getActivityAction(mergedProps));
  121. return mergedResult;
  122. }